import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class CinemaSystem {
    public static ArrayList<ScreeningHall> ScreeningHalls;
    private static final File PERSONNEL_LIST = new File("personnelList.txt"); //所有人员信息的文件
    public static ArrayList<User> userList; //所有人员表

    private static final File FILMS_LIST = new File("filmsStore.txt"); //所有电影清单的文件
    public static ArrayList<Film> filmsList; //电影表

    private static final File SCHEDULES_FILE = new File("schedulesStore.txt"); //排片清单文件
    public static ArrayList<Schedule> schedules = new ArrayList<>();

    private static final File LOG_FILE = new File("logFile.txt"); //日志文件
    public static final ArrayList<String[]> currentLog = new ArrayList<>(); //本次运行所产生的日志表

    public static User currentUser; //当前使用系统的用户

    public CinemaSystem() {
        ScreeningHalls = new ArrayList<>();
        ScreeningHalls.add(new ScreeningHall("白银厅"));
        ScreeningHalls.add(new ScreeningHall("黄金厅"));
        ScreeningHalls.add(new ScreeningHall("翡翠厅"));
        ScreeningHalls.add(new ScreeningHall("钻石厅"));
        ScreeningHalls.add(new ScreeningHall("宝石厅"));
    }

    public void start() { //系统入口
        init(); //从文件录入人员名单、电影等信息
        boolean exit = true;

        while (exit) { //主菜单
            switch (User.logging()) { //用户登录
                case ADMIN:
                    ((Administrator)currentUser).adminOperator();  //管理员操作程序
                    break;
                case MANAGER:
                    ((Manager)currentUser).managerOperator();  //经理操作程序
                    break;
                case STAFF:
                    ((Staff)currentUser).staffOperator();    //前台操作程序
                    break;
                case INVALID:           //回到主菜单分支
                    break;
                case null:
                    exit = false;
            }
        }
        upLoad(); //把该次运行的相关信息上传数据到文件中
        System.out.println("-> 系统正常结束！感谢使用....");
    }

    private void init() {
        userList = downLoadUserData();
        filmsList = downLoadFilmData();
        schedules = downLoadSchedulesData();
        // ...其他读取
    }

    private void upLoad() {
        upLoadUserData();
        upLoadFilmData();
        upLoadLog();
        upLoadSchedulesData();
    }

    private void upLoadLog() {
        //将currentLog写入 logFile.txt
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(LOG_FILE, true))) { //追加模式
            for (String[] tempLog : currentLog) {
                writer.write(tempLog[0] + " 事件: " + tempLog[1] + " 操作人: " + tempLog[2]);
                writer.newLine();
            }
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    private void upLoadUserData() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(PERSONNEL_LIST))) {
            String tableHead = "     ID    |    PassWord    |    UserName     |  RegisterTime  |   Type    |  Tele-Number  |";
            writer.write(tableHead);
            writer.newLine();
            for (User user : userList) {
                String perLine = String.format("%-10s   %-15s  %-15s     %-10s     %-9s    %-11s",
                        user.getUserID(),
                        Tool.spaceStack((15-user.getUserPassword().length())/2) + user.getUserPassword(),
                        Tool.spaceStack((15-user.getUserName().length())/2) + user.getUserName(),
                        user.getRegisterDate(),
                        Tool.spaceStack((10-user.getUserType().toString().length())/2) + user.getUserType().toString(),
                        user.getUserTel());
                writer.write(perLine);
                writer.newLine(); //换行
            }
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    private void upLoadFilmData() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILMS_LIST))) {
            for (Film film : filmsList) {
                writer.write(film.getName() + " " + film.getDirector() + " " +
                        film.getMainCharacter() + " " + film.getSynopsis() + " " +
                        film.getLength() + " " + film.getScore() + " " + film.getBasicPrice());
                writer.newLine(); //换行
            }
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    private void upLoadSchedulesData() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(SCHEDULES_FILE))) {
            for (Schedule schedule : CinemaSystem.schedules) {
                Film film = schedule.getFilm();
                ScreeningHall hall = schedule.getHall();

                // 格式化时间
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                String startTimeStr = sdf.format(schedule.getStartTime());

                // 计算结束时间（开始时间 + 电影时长）
                Calendar cal = Calendar.getInstance();
                cal.setTime(schedule.getStartTime());
                cal.add(Calendar.MINUTE, film.getLength());
                String endTimeStr = sdf.format(cal.getTime());

                // 处理已售座位信息
                String soldSeatsStr = "";
                Set<String> soldSeats = schedule.getSoldSeats();
                if (soldSeats != null && !soldSeats.isEmpty()) {
                    soldSeatsStr = String.join(",", soldSeats);
                }

                // 写入数据：电影名称 影厅类型 开始时间 结束时间 最终票价 已售座位
                // 格式：电影名称 影厅类型 开始日期 开始时间 结束日期 结束时间 票价 已售座位
                String[] startParts = startTimeStr.split(" ");
                String[] endParts = endTimeStr.split(" ");

                writer.write(film.getName() + " " +
                        hall.getType() + " " +
                        startParts[0] + " " + startParts[1] + " " +
                        endParts[0] + " " + endParts[1] + " " +
                        schedule.getFinalPrice() + " " +
                        soldSeatsStr);
                writer.newLine();
            }
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    private ArrayList<User> downLoadUserData() {
        ArrayList<User> tempList = new ArrayList<>();
        String tempID;
        String tempPassword;
        String tempName;
        String tempDate;
        LoginKey tempType;
        String tempTel;

        try (BufferedReader reader = new BufferedReader(new FileReader(PERSONNEL_LIST))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.charAt(0) == ' ') continue; //跳过初始行
                int index = 0;
                String[] parts = new String[6];
                int i = 0; //每行6个部分的索引parts[i]
                StringBuilder addPart = new StringBuilder();
                while (index < line.length()) {
                    if (line.charAt(index) != ' ')
                        addPart.append(line.charAt(index++));
                    else {
                        if (!addPart.isEmpty()) {
                            parts[i++] = addPart.toString();
                            addPart.setLength(0);
                        }
                        else index++;
                    }
                }
                parts[i] = addPart.toString(); //存入最后一个part

                tempID = parts[0];
                tempPassword = parts[1];
                tempName = parts[2];
                tempDate = parts[3];
                tempType = LoginKey.valueOf(parts[4]);
                tempTel = parts[5];
                switch (tempType) {
                    case ADMIN:
                        tempList.add(new Administrator(tempID, tempPassword, tempName, tempDate, tempTel));
                        break;
                    case MANAGER:
                        tempList.add(new Manager(tempID, tempPassword, tempName, tempDate, tempTel));
                        break;
                    case STAFF:
                        tempList.add(new Staff(tempID, tempPassword, tempName, tempDate, tempTel));
                        break;
                }
            }
        } catch (Exception e) {
            e.fillInStackTrace();
            return new ArrayList<>();
        }
        return tempList;
    }

    private ArrayList<Film> downLoadFilmData() {
        ArrayList<Film> tempList = new ArrayList<>();
        String tempName;
        String tempDirector;
        String tempMainCharacter;
        String tempSynopsis;
        int tempLength;
        int tempScore;
        int tempBasicPrice;

        try (BufferedReader reader = new BufferedReader(new FileReader(FILMS_LIST))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = new String[7];
                int index = 0, i = 0;
                StringBuilder addPart = new StringBuilder();
                while (index < line.length()) {
                    if (line.charAt(index) != ' ')
                        addPart.append(line.charAt(index++));
                    else {
                        if (!addPart.isEmpty()) {
                            parts[i++] = addPart.toString();
                            addPart.setLength(0);
                        }
                        else index++;
                    }
                }
                parts[i] = addPart.toString(); //存入最后一个part

                tempName = parts[0];
                tempDirector = parts[1];
                tempMainCharacter = parts[2];
                tempSynopsis = parts[3];
                tempLength = Integer.parseInt(parts[4]);
                tempScore = Integer.parseInt(parts[5]);
                tempBasicPrice = Integer.parseInt(parts[6]);
                tempList.add(new Film(tempName, tempDirector, tempMainCharacter,
                        tempSynopsis, tempLength, tempScore, tempBasicPrice));
            }
        } catch (Exception e) {
            e.fillInStackTrace();
            return new ArrayList<>();
        }
        return tempList;
    }

    private ArrayList<Schedule> downLoadSchedulesData() {
        ArrayList<Schedule> tempList = new ArrayList<>();

        try (BufferedReader reader = new BufferedReader(new FileReader(SCHEDULES_FILE))) {
            String line;
            int lineNumber = 0;

            while ((line = reader.readLine()) != null) {
                lineNumber++;
                if (line.trim().isEmpty()) {
                    continue; // 跳过空行
                }

                // 使用更简单的方式分割字段
                String[] parts = line.split(" ", 8); // 最多分割8次，保留最后一个字段完整

                // 检查字段数量（至少需要7个字段：电影、影厅、开始日期、开始时间、结束日期、结束时间、票价）
                if (parts.length < 7) {
                    System.out.println("警告：第" + lineNumber + "行数据格式错误（字段不足），跳过: " + line);
                    continue;
                }

                try {
                    String tempFilmName = parts[0];
                    String tempHallType = parts[1];
                    String tempStartDate = parts[2];
                    String tempStartTime = parts[3];
                    float tempFinalPrice = Float.parseFloat(parts[6]);

                    String tempSoldSeatsStr = parts.length > 7 ? parts[7] : ""; // 已售座位信息（可选）

                    // 构建完整的时间字符串
                    String tempStartTimeStr = tempStartDate + " " + tempStartTime;

                    // 查找对应的电影对象
                    Film film = findFilmByName(tempFilmName);
                    if (film == null) {
                        System.out.println("警告：第" + lineNumber + "行未找到电影《" + tempFilmName + "》，跳过该排片");
                        continue;
                    }

                    // 查找对应的影厅对象
                    ScreeningHall hall = findHallByType(tempHallType);
                    if (hall == null) {
                        System.out.println("警告：第" + lineNumber + "行未找到影厅类型'" + tempHallType + "'，跳过该排片");
                        continue;
                    }

                    // 解析时间
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    Date startTime = sdf.parse(tempStartTimeStr);

                    // 创建排片对象
                    Schedule schedule = new Schedule(film, hall, startTime);
                    schedule.setFinalPrice(tempFinalPrice);

                    // 加载已售座位信息
                    if (tempSoldSeatsStr != null && !tempSoldSeatsStr.trim().isEmpty()) {
                        Set<String> soldSeats = new HashSet<>();
                        String[] seatArray = tempSoldSeatsStr.split(",");
                        for (String seat : seatArray) {
                            String trimmedSeat = seat.trim();
                            if (!trimmedSeat.isEmpty()) {
                                // 验证座位格式
                                if (isValidSeatFormat(trimmedSeat, hall)) {
                                    soldSeats.add(trimmedSeat);
                                } else {
                                    System.out.println("警告：第" + lineNumber + "行座位格式错误: " + trimmedSeat);
                                }
                            }
                        }
                        schedule.setSoldSeats(soldSeats);
                    }

                    tempList.add(schedule);

                } catch (ParseException e) {
                    System.out.println("警告：第" + lineNumber + "行时间格式错误，跳过: " + line);
                } catch (NumberFormatException e) {
                    System.out.println("警告：第" + lineNumber + "行票价格式错误，跳过: " + line);
                } catch (Exception e) {
                    System.out.println("警告：第" + lineNumber + "行数据解析错误，跳过: " + line);
                }
            }
        } catch (IOException e) {
            System.out.println("读取排片数据文件失败: " + e.getMessage());
            return new ArrayList<>();
        }

        return tempList;
    }

    // 辅助方法：验证座位格式是否正确
    private boolean isValidSeatFormat(String seat, ScreeningHall hall) {
        try {
            String[] parts = seat.split("-");
            if (parts.length != 2) return false;

            int row = Integer.parseInt(parts[0]);
            int col = Integer.parseInt(parts[1]);

            // 检查座位是否在影厅范围内
            return row >= 1 && row <= hall.getRows() && col >= 1 && col <= hall.getColumns();
        } catch (NumberFormatException e) {
            return false;
        }
    }

    // 辅助方法：根据电影名称查找电影对象
    private Film findFilmByName(String filmName) {
        for (Film film : CinemaSystem.filmsList) {
            if (film.getName().equals(filmName)) {
                return film;
            }
        }
        return null;
    }

    // 辅助方法：根据影厅类型查找影厅对象
    private ScreeningHall findHallByType(String hallType) {
        for (ScreeningHall hall : CinemaSystem.ScreeningHalls) {
            if (hall.getType().equals(hallType)) {
                return hall;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        (new CinemaSystem()).start();
    }
}